from __future__ import division

from gameset.phoenicia.base import *


class Plant(Good):
    singular =_ ('Plant')
    plural   =_ ('Plants')


class EdiblePlant(Food, Plant):
    singular =_ ('Edible Plant')
    plural   =_ ('Edible Plants')


class InediblePlant(RawMaterial, Plant):
    singular =_ ('Inedible Plant')
    plural   =_ ('Inedible Plants')


class Field(Building, FertilityDependent):
    size =_ (3)
    cost =_ (50)
    
    plant         =_ (None)
    resistance    =_ (0.5)
    seed_month    =_ (None)
    harvest_month =_ (None)
    max_seeds     =_ (None)
    weed_chance   =_ (None)
    
    is_passable =_ (True)
    
    seeds  = Attribute(initial = 0, writable = True)
    growth = Attribute(initial = 0, writable = True)
    weeds  = Attribute(initial = 0, writable = True, clamp = (0, 1))
    
    @property
    def stores(self):
        return self.plant(self.max_seeds)
    
    @property
    def efficiency(self):
        return self.fertility_modifier * (1 - self.weeds)
    
    @property
    def growth_months(self):
        if self.seed_month < self.harvest_month:
            return (self.harvest_month - self.seed_month - 1)
        else:
            return (self.harvest_month - self.seed_month - 1) + self.calendar.months_per_year
    
    @property
    def is_sowing(self):
        return self.calendar.month == self.seed_month
    
    @property
    def is_harvesting(self):
        return (self.growth > 0 or not self.storage.is_empty) and self.calendar.month == self.harvest_month
    
    @property
    def is_growing(self):
        return self.seeds > 0 and not self.is_sowing and not self.is_harvesting
    
    @property
    def phase(self):
        if self.is_sowing:
            return 'Sowing'
        elif self.is_harvesting:
            return 'Harvesting'
        elif self.is_growing:
            return 'Growing'
        else:
            return 'Barren'
    
    @property
    def next_phase(self):
        if self.is_sowing:
            return 'Growing in %dd' % self.calendar.days_until_start_of_month(self.seed_month + 1)
        elif self.is_harvesting:
            return 'Barren in %dd' % self.calendar.days_until_start_of_month(self.harvest_month + 1)
        elif self.is_growing:
            return 'Harvesting in %dd' % self.calendar.days_until_start_of_month(self.harvest_month)
        else:
            return 'Sowing in %dd' % self.calendar.days_until_start_of_month(self.seed_month)
    
    def sow(self, seeds):
        if not self.is_sowing:
            return
        
        self.seeds += seeds
        self.seeds  = min(self.seeds, self.max_seeds)
    
    def weed(self):
        self.weeds *= 0.9
    
    def day(self, day, month, year):
        if self.is_growing:
            self.growth += self.calendar.days(self.calendar.per_month(self.seeds)) / self.growth_months * self.efficiency
            
            if self.one_in(self.weed_chance):
                self.weeds += 0.01
                self.weeds *= 1.2
        elif self.is_harvesting:
            self.create(self.plant(int(self.growth)))
            self.weeds  = 0
            self.seeds  = 0
            self.growth = 0
        elif not self.storage.is_empty:
            self.storage.remove_all_goods()
    
    @property
    def state(self):
        return {'Seeds'      : lambda: self.seeds,
                'Growth'     : lambda: int(self.growth),
                'Weeds'      : lambda: '%.2f%%' % (self.weeds * 100),
                'Phase'      : lambda: self.phase,
                'Phase Until': lambda: self.next_phase}


class Farmer(Seeker):
    color    =_ (Yellow.dark + Black)
    speed    =_ (8)
    radius   =_ (7)
    capacity =_ (50)
    
    field = Attribute(writable = True)
    
    def on_idle(self):
        if self.one_in(500):
            self.move_home()
        elif self.one_in(50) or self.field is None:
            self.choose_field()
        else:
            self.move_to_random(list(self.field.area.positions))
    
    def on_arrival_home(self):
        if self.storage.is_empty:
            self.destroy()
        else:
            self.unload_into(self.home)
    
    def choose_field(self):
        self.field = self.tile.random_nearby(Field, radius = self.radius)
        
        if self.field is None and self.one_in(5):
            self.move_home()
    
    def work_on(self, field):
        if field.is_harvesting:
            self.load_from(field)
            
            if not self.storage.is_empty:
                self.move_home()
        elif field.is_sowing:
            field.sow(25)
        elif field.is_growing:
            field.weed()
        else:
            self.on_idle()
    
    def day(self, day, month, year):
        building = self.tile.building
        
        if isinstance(building, Field):
            self.work_on(building)


class Farm(StaffedBuilding):
    name       =_ ('Farm')
    color      =_ (Brown)
    size       =_ (3)
    cost       =_ (125)
    staff      =_ (20)
    agents     =_ (6)
    stores     =_ (Plant(800))
    supply     =_ ([Plant])
    profession =_ (Farmer)
    
    @property
    def spawn_point(self):
        return self.access_point
